package com.daniel.authytest.client;

import com.daniel.authytest.shared.Constants;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ScrollPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Authytest implements EntryPoint
{
    /**
     * Create a remote service proxy to talk to the server-side Greeting service.
     */
    private final AuthyTestServiceAsync authyTestService = GWT.create( AuthyTestService.class );

    private RootPanel rootPanel;
    private TextBox txtbxGithuburl;
    private TextBox txtbxFindtext;
    private CheckBox chckbxCaseSensitive;
    private HTMLPanel alertPanel;
    private VerticalPanel panelResult;
    private ScrollPanel scrollPanel;

    private RootPanel loadingModal;
    private RootPanel loadingMessage;

    /**
     * This is the entry point method.
     */
    public void onModuleLoad( )
    {
        rootPanel = RootPanel.get( "main" );
        loadingModal = RootPanel.get( "loader" );
        loadingMessage = RootPanel.get( "load-message" );

        VerticalPanel verticalPanel = new VerticalPanel( );
        rootPanel.add( verticalPanel );
        verticalPanel.setWidth( "100%" );

        alertPanel = new HTMLPanel( "<div id=\"alerts\" class=\"alert \"><a class=\"close\" data-dismiss=\"alert\" href=\"#\">x</a><div id=\"alert-mess\">alert Mess</div></div>" );
        verticalPanel.add( alertPanel );
        alertPanel.setVisible( false );

        Label lblGithubUrl = new Label( "GitHub URL" );
        verticalPanel.add( lblGithubUrl );
        rootPanel.add( verticalPanel );

        txtbxGithuburl = new TextBox( );
        verticalPanel.add( txtbxGithuburl );

        Label lblFindText = new Label( "Find text" );
        verticalPanel.add( lblFindText );

        txtbxFindtext = new TextBox( );
        verticalPanel.add( txtbxFindtext );
        KeyDownHandler enterHandler = new KeyDownHandler( )
        {

            @Override
            public void onKeyDown( KeyDownEvent event )
            {
               
                if( event.getNativeEvent( ).getKeyCode( ) == KeyCodes.KEY_ENTER )
                {
                    alertPanel.setVisible( false );
                    scrollPanel.setVisible( false );
                    setLoading( "Searching..." );
                    searchOnGitHug( );
                }

            }
        };
        txtbxFindtext.addKeyDownHandler( enterHandler );
        txtbxGithuburl.addKeyDownHandler( enterHandler );

        chckbxCaseSensitive = new CheckBox( "Case sensitive" );
        verticalPanel.add( chckbxCaseSensitive );

        Button btnSearch = new Button( "Search" );
        btnSearch.addClickHandler( new ClickHandler( )
        {
            public void onClick( ClickEvent event )
            {
                alertPanel.setVisible( false );
                scrollPanel.setVisible( false );
                setLoading( "Searching..." );
                searchOnGitHug( );
            }
        } );
        btnSearch.setStyleName( "btn btn-large btn-primary" );
        verticalPanel.add( btnSearch );
        btnSearch.setWidth( "100%" );

        scrollPanel = new ScrollPanel( );
        scrollPanel.setStyleName( "result-table well" );
        verticalPanel.add( scrollPanel );
        scrollPanel.setWidth( "940px" );
        scrollPanel.setVisible( false );

        panelResult = new VerticalPanel( );
        scrollPanel.setWidget( panelResult );
        panelResult.setSize( "100%", "100%" );

        stopLoading( );
    }
    public void searchOnGitHug( )
    {
        authyTestService.searchOnGitHug( txtbxGithuburl.getText( ), txtbxFindtext.getText( ), chckbxCaseSensitive.getValue( ), new AsyncCallback<String>( )
        {

            @Override
            public void onFailure( Throwable caught )
            {
                alertPanel.getElementById( "alert-mess" ).setInnerHTML( caught.getMessage( ) );
                alertPanel.getElementById( "alerts" ).setClassName( "alert alert-error" );
                alertPanel.setVisible( true );
                scrollPanel.setVisible( false );
                stopLoading( );
            }

            @Override
            public void onSuccess( String result )
            {
                setLoading( "Rendering results..." );
                renderResults( result );
                stopLoading( );
            }
        } );
    }

    public void renderResults( String resultJson )
    {
        JSONValue value = JSONParser.parseLenient( resultJson );
        JSONObject object = value.isObject( );
        Tree tree = new Tree( );

        panelResult.clear( );

        String textFind = object.get( Constants.FIND_TEXT ).isString( ).stringValue( );
        String project = object.get( Constants.PROJECT ).isString( ).stringValue( );
        String user = object.get( Constants.USER ).isString( ).stringValue( );
        String histsCount = object.get( Constants.HITS_COUNT ).isString( ).stringValue( );
        String filesCount = object.get( Constants.FILES_COUNT ).isString( ).stringValue( );

        panelResult.add( new HTML( "search <strong>\"" + textFind + "\"</strong> in project " + user + "/" + project + " ( " + histsCount + " hits in " + filesCount + " files ) " ) );

        JSONArray files = object.get( Constants.FILES ).isArray( );

        for( int i = 0; i < files.size( ); i++ )
        {
            JSONObject fileObj = files.get( i ).isObject( );

            String fileName = fileObj.get( Constants.FILE_NAME ).isString( ).stringValue( );
            String fileUrl = fileObj.get( Constants.FILE_URL ).isString( ).stringValue( );
            String fileHitsCount = fileObj.get( Constants.HITS_COUNT ).isString( ).stringValue( );
            HTML htmlFileItem = new HTML( "<a href=\"" + fileUrl + "\" target=\"_blank\" >" + fileName + " ( " + fileHitsCount + " hits ) </a>" );
            // panelResult.add( htmlFileItem );

            TreeItem treeItem = tree.addItem( htmlFileItem );

            JSONArray hitLines = fileObj.get( Constants.FILE_LINES ).isArray( );
            for( int j = 0; j < hitLines.size( ); j++ )
            {
                String lineObj = hitLines.get( j ).isString( ).toString( );
                lineObj = lineObj.substring( 1, lineObj.length( ) - 1 );
                HTML line = new HTML( SafeHtmlUtils.fromString( lineObj ).asString( ).replaceAll( textFind, "<strong>" + textFind + "</strong>" ) );
                treeItem.addItem( line );
                // panelResult.add( line );
            }
            treeItem.setState( true );

        }

        panelResult.add( tree );
        scrollPanel.setVisible( true );
    }

    public void setLoading( String message )
    {
        loadingMessage.clear( );
        loadingMessage.add( new HTML( "<h1>" + message + "</h1>" ) );

        loadingModal.setVisible( true );
        loadingMessage.setVisible( true );
    }
    public void stopLoading( )
    {
        loadingModal.setVisible( false );
        loadingMessage.setVisible( false );
    }
}
